/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bitzer.google;

import com.google.gdata.client.contacts.ContactQuery;
import com.google.gdata.client.contacts.ContactsService;
import com.google.gdata.data.DateTime;
import com.google.gdata.data.Link;
import com.google.gdata.data.PlainTextConstruct;
import com.google.gdata.data.contacts.ContactEntry;
import com.google.gdata.data.contacts.ContactFeed;
import com.google.gdata.data.extensions.Email;
import com.google.gdata.data.extensions.FamilyName;
import com.google.gdata.data.extensions.GivenName;
import com.google.gdata.data.extensions.Name;
import com.google.gdata.util.AuthenticationException;
import com.google.gdata.util.ServiceException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

/**
 *
 * @author ali
 */
    public class Contacts {

    /**
     * instance of singleton class
     */
    private static Contacts _instance = null;
    public  int recordCount    =  0 ;
    private static final String fileSeperator = System.getProperty("file.separator");
    /**
     * Service used to communicate with contacts feed.
     */
    private static ContactsService service;

    public Contacts() {

        service = new ContactsService("Google-ContactsApp-3");
    }

    public static Contacts instance() {
        if (_instance == null) {
            _instance = new Contacts();
        }
        return _instance;
    }

    public void authenticate(String username, String password) throws AuthenticationException {
        if (username == null || password == null) {
            return;
        }
        service.setUserCredentials(username, password);
    }

    public ContactsService getService() {
        return service;
    }

    public ContactFeed getFeed(String lastModifiedOn, int startIndex, int numberOfRows , HttpServletRequest request) {

        try {
            
            HttpSession session = request.getSession();
            URL feedUrl = new URL(Constants.CONTACTS_FEED_URL);
            
            if (session.getAttribute("recordCount") == null) {
                
                ContactQuery baseQuery = new ContactQuery(feedUrl);
                baseQuery = setQueryParameters(baseQuery, request);
                baseQuery.setStartIndex(1);
                baseQuery.setMaxResults(100000);
                ContactFeed feed = service.getFeed(baseQuery, ContactFeed.class);
                recordCount = feed.getEntries().size();
                session.setAttribute("recordCount", new Integer(recordCount));
                
            }else{
                recordCount = ((Integer)session.getAttribute("recordCount")).intValue();
            }
            
            ContactQuery query = new ContactQuery(feedUrl);
            query = setQueryParameters(query, request);
            
            DateTime modifiedOn = Utils.getDateTimeFromString(lastModifiedOn);
            
            if(modifiedOn != null){
                query.setStringCustomParameter("showdeleted","true");
                query.setShowDeleted(Boolean.TRUE);
                query.setUpdatedMin(modifiedOn);
            }
            query.setStartIndex(startIndex);
            query.setMaxResults(numberOfRows);
            
            return service.getFeed(query, ContactFeed.class);
            
        } catch (Exception e) {
            return null;
        }
    }

    public static ContactQuery setQueryParameters(ContactQuery query , HttpServletRequest request){
        query = setSearchParameters(query,request);
        query = setSortParameters(query, request);
        return query;
    }

    public static ContactQuery setSearchParameters(ContactQuery query,HttpServletRequest request){

        String queryString = request.getQueryString();
        ArrayList searchColumns = Utils.getParams(queryString, "searchColumn");
        if(!searchColumns.isEmpty()){
            ArrayList searchValues = Utils.getParams(queryString, "searchValue");
            if(searchColumns.size() == searchValues.size()){
                for(int i = 0; i<searchColumns.size();i++){
                    query.setFullTextQuery((String)searchValues.get(i));
                }
            }
        }
        return query;
    }

    public static ContactQuery setSortParameters(ContactQuery query,HttpServletRequest request){

        String queryString = request.getQueryString();

        ArrayList sortColumns = Utils.getParams(queryString, "sortByColumn");
        ArrayList sortByOrder = Utils.getParams(queryString, "sortByOrder");
        
        if (!sortColumns.isEmpty()) {
            query.setStringCustomParameter("orderby","lastmodified");
        }
        if(!sortByOrder.isEmpty()){
            String order = (String)sortByOrder.get(0);
            if(order.equals("DESC")){
                query.setStringCustomParameter("sortorder","descending");
            }
            else{
                query.setStringCustomParameter("sortorder","ascending");
            }
        }
        return query;
    }

    public static String getPhoto(ContactEntry entry, String contextPath, String relativePath, String username) {

        Link photoLink = entry.getContactPhotoLink();
       
        File imgFile = null;
        String imgPath = null;
        String fileName = null;
        String etag = photoLink.getEtag();
        if (photoLink != null) {

            if ((etag != null)) {
                try {

                    fileName = entry.getSelfLink().getHref().substring(
                    entry.getSelfLink().getHref().lastIndexOf('/') + 1);
            
                    imgPath = contextPath + "images"+fileSeperator+"contacts"+fileSeperator+username + "_" + fileName;
                    imgFile = new File(imgPath + ".jpeg");
                    
                    if(!imgFile.exists() || (imgFile.lastModified() < entry.getUpdated().getValue())){
                    InputStream in = service.getStreamFromLink(photoLink);
                    OutputStream out = new FileOutputStream(imgFile);

                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) > 0) {
                        out.write(buf, 0, len);
                    }
  
                    out.close();
                    }
                    return relativePath + "/images/contacts/" + username + "_" + fileName + ".jpeg";

                } catch (Exception e) {
                    //return relativePath + "/images/contacts/person_placeholder.jpg";
                    return "";
                }
            }

        }

        //return relativePath + "/images/contacts/person_placeholder.jpg";
        return "";
    }

    public ContactEntry createContact(String firstName, String lastName, String wemail , 
            String title , String notes , String hemail , String oemail)
            throws ServiceException, IOException {
        // Create the entry to insert

        ContactEntry contact = new ContactEntry();
        final String NO_YOMI = null;
        
        contact.setTitle(new PlainTextConstruct(title));
        contact.setContent(new PlainTextConstruct(notes));

        Name name = new Name();
        GivenName givenName = new GivenName(firstName,NO_YOMI);
        name.setGivenName(givenName);

        FamilyName familyName = new FamilyName(lastName,NO_YOMI);
        name.setFamilyName(familyName);
       
        contact.setName(name);

        if(hemail != null){
        Email primaryMail = new Email();
        primaryMail.setAddress(hemail);
        primaryMail.setRel("http://schemas.google.com/g/2005#home");
        primaryMail.setPrimary(true);
        contact.addEmailAddress(primaryMail);
        }
        
        if(wemail != null){
        Email secondaryMail = new Email();
        secondaryMail.setAddress(wemail);
        secondaryMail.setRel("http://schemas.google.com/g/2005#work");
        secondaryMail.setPrimary(false);
        contact.addEmailAddress(secondaryMail);
        }

        if(hemail != null){
        Email otherMail = new Email();
        otherMail.setAddress(oemail);
        otherMail.setRel("http://schemas.google.com/g/2005#other");
        otherMail.setPrimary(false);
        contact.addEmailAddress(otherMail);
        }

        // Ask the service to insert the new entry
        URL postUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
        return service.insert(postUrl, contact);
    }

    public static void main (String args[]) throws AuthenticationException
    {
//        Contacts contacts = Contacts.instance();
//        contacts.authenticate("jose@web1infotech.com", "");
//        ContactFeed feed = contacts.getFeed("", 1, 300,null);
//
//         for (int i = 0; i < feed.getEntries().size(); i++) {
//             ContactEntry entry = feed.getEntries().get(i);
//             if(entry.hasName())
//             System.out.println(entry.getName().getGivenName().getValue());
//
//             
//        }
        
        DateTime time   = Utils.getDateTimeFromString("2010-03-26 00:00:00 EST");
        System.out.println(time);
    }
}
